package pool;

/**
 * @author ex_chenzy59
 * @since 2025/4/11
 * 池中的对象
 * 所有时间字段都是long型时间戳
 */
public class PoolObject<T> {
    private PooledObjectState state = PooledObjectState.IDLE;
    private final long createTime = System.currentTimeMillis();
    /*最后借出时间*/
    private volatile long lastBorrowTime = createTime;
    /*最后使用时间*/
    private volatile long lastUseTime = createTime;
    /*最后归还时间*/
    private volatile long lastReturnTime = createTime;
    private volatile boolean logAbandoned;
    private volatile long borrowedCount;
    private T data;

    public T get(){
        return data;
    }
    public synchronized void invalidate() {
        state = PooledObjectState.INVALID;
    }

    /*开始驱逐*/
    public boolean startEvict() {
        if (state == PooledObjectState.IDLE) {
            state = PooledObjectState.EVICTION;
            return true;
        }
        return false;
    }

    /**
     * 得到对象空闲时长,单位毫秒
     * 以下两种情况可能导致结果负数
     * 1. 另一个线程在计算窗口期间更新了lastReturnInstant
     * 2. System.currentTimeMillis() 不是单调递增的（例如，系统时间被回调）
     */
    public long getDurationIdle(){
       var result=System.currentTimeMillis()-lastReturnTime;
        return result < 0 ? 0 : result;
    }

    /**
     * 判断对象是否空闲太久,超过指定时长.超过返回true
     * @param maxIdleDuration 最大空闲时长,单位秒
     */
    public boolean isMaxIdle(long maxIdleDuration){
        return getDurationIdle()>maxIdleDuration*1000;
    }
    public static enum PooledObjectState{
        /**
         * 在队列,空闲 In the queue, not in use.
         */
        IDLE,

        /**
         * 不在队列,使用中 In use.
         */
        ALLOCATED,

        /**
         * 在队列,开始驱逐 In the queue, currently being tested for possible eviction.
         */
        EVICTION,

        /**
         * 不在队列，目前正在测试是否可能被驱逐。在测试期间尝试借用该对象，这将其从队列中移除。一旦驱逐测试完成，它应该被返回到队列的头部。
         *
         * Not in the queue, currently being tested for possible eviction. An attempt to borrow the object was made while
         * being tested which removed it from the queue. It should be returned to the head of the queue once eviction
         * testing completes.
         */
        EVICTION_RETURN_TO_HEAD,

        /**
         * 在队列,开始有效性验证 In the queue, currently being validated.
         */
        VALIDATION,

        /**
         * 不在队列中，目前正在验证。对象在验证时被借用，由于配置了testOnBorrow，它被从队列中移除并预分配。一旦验证完成，它应该被分配。
         * Not in queue, currently being validated. The object was borrowed while being validated and since testOnBorrow was
         * configured, it was removed from the queue and pre-allocated. It should be allocated once validation completes.
         */
        VALIDATION_PREALLOCATED,

        /**
         * 未在队列中，当前正在验证。尝试借用该对象时，之前正在测试是否驱逐它，这将其从队列中移除。一旦验证完成，它应返回到队列的头部。
         * Not in queue, currently being validated. An attempt to borrow the object was made while previously being tested
         * for eviction which removed it from the queue. It should be returned to the head of the queue once validation
         * completes.
         */
        VALIDATION_RETURN_TO_HEAD,

        /**
         * 维护失败（例如驱逐测试或验证）并将被/已被销毁。
         * Failed maintenance (e.g. eviction test or validation) and will be / has been destroyed
         */
        INVALID,

        /**
         * 视为放弃，将被作废。 Deemed abandoned, to be invalidated.
         */
        ABANDONED,

        /**
         * 返回泳池。 Returning to the pool.
         */
        RETURNING
        ;
    }
}
